package com.frikinet.lifeguard.gui;

import static ch.lambdaj.Lambda.convert;

import java.awt.Color;
import java.awt.Cursor;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;
import java.util.TreeSet;

import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.border.EtchedBorder;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ch.lambdaj.function.convert.Converter;

import com.frikinet.lifeguard.App;
import com.frikinet.lifeguard.events.MonthSelectedListener;
import com.frikinet.lifeguard.events.YearMonthSelectedEvent;
import com.frikinet.lifeguard.model.Post;
import com.frikinet.lifeguard.model.User;

public class MonthNavigation extends JPanel implements MonthSelectedListener
{
	private static final long serialVersionUID = 1L;
	private static final Logger log = LoggerFactory.getLogger(PostViewer.class);
	
	private Font clickFont, currentFont;
	
	private JLabel previousMonth, nextMonth;
	private JLabel currentMonth;
	
	private Calendar month;
	private User user;
	
	public MonthNavigation()
	{
		super(new GridLayout(1, 3));
		
		App.events.addMonthSelectedListener(this);
		
		Font defaultFont = UIManager.getDefaults().getFont("Label.font");
		clickFont = new Font(defaultFont.getName(), Font.BOLD, defaultFont.getSize()+2);
		currentFont = new Font(defaultFont.getName(), defaultFont.getStyle(), defaultFont.getSize()+2);
		
		
		buildGUI();
	}
	
	private void buildGUI()
	{
		setBorder(BorderFactory.createEtchedBorder(EtchedBorder.RAISED));
		
		JPanel west = new JPanel(new FlowLayout(FlowLayout.LEFT));
		previousMonth = setupClickLabel(MonthNavigationType.PREVIOUS);
		west.add(previousMonth);
		add(west);
		
		JPanel center = new JPanel(new FlowLayout(FlowLayout.CENTER));
		currentMonth = new JLabel(" ");
		currentMonth.setFont(currentFont);
		center.add(currentMonth);
		add(center);
		
		JPanel east = new JPanel(new FlowLayout(FlowLayout.RIGHT));
		nextMonth = setupClickLabel(MonthNavigationType.NEXT);
		east.add(nextMonth);
		add(east);
	}
	
	private JLabel setupClickLabel(MonthNavigationType type)
	{
		JLabel label = new JLabel(" ");
		label.setFont(clickFont);
		label.setForeground(Color.blue);
		label.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
		label.addMouseListener(new MonthNavigationListener(type));
		return label;
	}
	
	@Override
	public void monthSelected(YearMonthSelectedEvent event)
	{
		List<Calendar> months = new ArrayList<Calendar>(Arrays.asList(new TreeSet<Calendar>(convert(event.getUser().getPosts(), new Converter<Post, Calendar>() {
			@Override
			public Calendar convert(Post post)
			{
				Calendar cp = Calendar.getInstance();
				cp.setTime(post.getDate());
				Calendar r = Calendar.getInstance();
				r.setTimeInMillis(0);
				r.set(cp.get(Calendar.YEAR), cp.get(Calendar.MONTH), 1);
				return r;
			}
		})).toArray(new Calendar[]{})));
		
		
		month = Calendar.getInstance();
		month.setTimeInMillis(0);
		month.set(event.getYear(), event.getMonth()-1, 1);
		user = event.getUser();
		
		currentMonth.setText(StringUtils.capitalize(App.i18n.translate("comp.month.navigation.month.current", month.getTime())));
		
		int index = months.indexOf(month);
		
		if(index > 0)
		{
			Calendar previous = months.get(index-1);
			previousMonth.setText(String.format("< %s", App.i18n.translate("comp.month.navigation.month.click", previous.getTime())));
		} 
		else
		{
			previousMonth.setText(" ");
		}
		
		if(index < months.size() - 1)
		{
			Calendar next = months.get(index + 1);
			nextMonth.setText(String.format("%s >", App.i18n.translate("comp.month.navigation.month.click", next.getTime())));
		}
		else
		{
			nextMonth.setText(" ");
		}
	}
	
	private enum MonthNavigationType
	{
		PREVIOUS, NEXT;
	}
	
	private class MonthNavigationListener extends MouseAdapter
	{
		private MonthNavigationType type;
		
		private MonthNavigationListener(MonthNavigationType type)
		{
			this.type = type;
		}

		@Override
		public void mouseReleased(MouseEvent e)
		{
			log.trace(String.format("Month Navigation button clicked: %s", type));
			Calendar month = (Calendar)MonthNavigation.this.month.clone();
			if(type==MonthNavigationType.PREVIOUS)
			{
				month.add(Calendar.MONTH, -1);
			}
			else
			{
				month.add(Calendar.MONTH, 1);
			}
			App.events.fireMonthSelected(new YearMonthSelectedEvent(this,user, month.get(Calendar.YEAR), month.get(Calendar.MONTH)+1));
		}
	}
}
